//
//  YCPreloadScrollView.m
//  TsinghuaSNS
//
//  Created by SL on 13-11-12.
//  Copyright (c) 2013年 cdeledu. All rights reserved.
//

#import "YCPreloadScrollView.h"

#define PreloadTotalNumber          3               //预加载view个数 1+2n

#define SetViewTag(i)               24371+i         //设置view标志
#define GetViewTag(i)               i-24371         //获取view标志

//第一页向前翻或者最后一页向后翻
typedef void (^MoveExtremum)(ScrollPageTip tip);
typedef UIView *(^FetchPage)(NSInteger page);
typedef void (^ChangePage)(NSInteger page);

@interface YCPreloadScrollView()<UIScrollViewDelegate,UIGestureRecognizerDelegate>

@property (nonatomic,copy) MoveExtremum moveExtremum;
@property (nonatomic,copy) FetchPage pageBlock;
@property (nonatomic,copy) ChangePage changeBlock;

@end

@implementation YCPreloadScrollView

- (void)dealloc{
#ifdef DEBUG
    NSLog(@"dealloc -- %@",self.class);
#endif
}

- (id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
        [scrollView setPagingEnabled:YES];
        [scrollView setShowsHorizontalScrollIndicator:NO];
        [scrollView setShowsVerticalScrollIndicator:NO];
        [scrollView setDelegate:self];
        [scrollView setBounces:NO];
        [scrollView setScrollsToTop:NO];
        [self addSubview:scrollView];
        self.mainScrollView = scrollView;
    }
    return self;
}

- (UIView *)getShowView:(NSInteger)page{
    return nil;
}

- (void)fetchShowView:(UIView *(^)(NSInteger page))page{
    self.pageBlock = page;
}

- (void)changeShowPage:(void(^)(NSInteger index))page{
    self.changeBlock = page;
}

- (void)getMoveExtremum:(void(^)(ScrollPageTip tip))move{
    self.moveExtremum = move;
    [self.mainScrollView setBounces:YES];
}

- (UIView *)getCurrentShowView{
    return [self.mainScrollView viewWithTag:SetViewTag(self.curPage)];
}

/**
 *  设置页面显示view总个数
 */
-(void)setTotalNumber:(NSInteger)total{
    _totalNumber = total;
    //调用此方法时，一般是初始化或者重新设置数据源的时候
    //PS：重新设置数据源的时候，不希望去调用UIScrollView去执行代理事件，先设置为nil
    self.mainScrollView.delegate = nil;
    //根据数据源设置mainScrollView的内容大小
    if (_totalNumber >= 3) {
        [self.mainScrollView setContentSize:CGSizeMake(self.bounds.size.width*3, 0)];
    }else{
        [self.mainScrollView setContentSize:CGSizeMake(self.bounds.size.width*_totalNumber, 0)];
    }
    self.mainScrollView.delegate = self;
}

/**
 *  设置当前页面
 */
-(void)setCurPage:(NSInteger)page{
    if (page >= self.totalNumber && page < 0) {
        //防止数组越界
        return;
    }
    
    _curPage = page;
    
    //显示数据
    [self loadData];
    
    if (self.changeBlock) {
        //切换的页面
        self.changeBlock(page);
    }
}

/**
 *  获取显示页面
 */
- (void)loadData{
    //从scrollView上移除没有用的uiview
    NSArray *subViews = [self.mainScrollView subviews];
    for (UIView *view in subViews) {
        NSInteger tag = GetViewTag(view.tag);
        if (!((tag<=(_curPage+(PreloadTotalNumber-1)/2)) && (tag>=(_curPage-(PreloadTotalNumber-1)/2)))) {
            //移除预加载以外题目
#ifdef DEBUG
            NSLog(@"移除预加载以外题目====%ld",(long)tag);
#endif
            [view removeFromSuperview];
        }
    }
    
    //加载预加载以内题目
    for (int i = 0; i < PreloadTotalNumber; i++) {
        
        //预加载题目的位置
        NSInteger number = _curPage-(PreloadTotalNumber-1)/2+i;
        
        if (number<0 || number>=_totalNumber) {
            continue;
        }
        
        //取出当前题目
        UIView *v = [self.mainScrollView viewWithTag:SetViewTag(number)];
        
        if (!v) {
#ifdef DEBUG
            NSLog(@"创建一个新的页面======%ld",(long)number);
#endif
            if (self.pageBlock) {
                v = self.pageBlock(number);
            }else{
                v = [self getShowView:number];
            }
            [v setTag:SetViewTag(number)];
            [self.mainScrollView addSubview:v];
        }
        
        //view的位置
        NSInteger ssss = i-(PreloadTotalNumber-1)/2+1;
        if (_curPage==0) {
            //第一页
            ssss = i-(PreloadTotalNumber-1)/2;
        }else if (_curPage==_totalNumber-1 && _totalNumber>=3){
            //最后一页
            ssss = i-(PreloadTotalNumber-1)/2+2;
        }
        [v setFrame:CGRectMake(self.bounds.size.width*ssss, 0, self.frame.size.width, self.frame.size.height)];
    }
    
    //mainScrollView显示位置
    [self scrollViewDidEndDecelerating:nil];
}

/**
 *  设置当前页数
 */
- (NSInteger)validPageValue:(NSInteger)value{
    if(value == -1) value = _totalNumber - 1;
    if(value == _totalNumber) value = 0;
    return value;
}

#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    //开启弹簧效果才能执行
    //捕获第一页向前翻或者最后一页向后翻事件之后，只执行一次事件
    if (self.moveExtremum && !self.GestureEnabled) {
        [scrollView setBounces:YES];
    }
}

- (void)scrollViewDidScroll:(UIScrollView *)ScrollView{
    int x = ScrollView.contentOffset.x;
    if (x<0) {
        [ScrollView setBounces:NO];
        [ScrollView setContentOffset:CGPointMake(0, 0) animated:NO];
        if (_curPage==0) {
            [self TheFirstOnePage];
        }
    }else if(x > self.mainScrollView.contentSize.width-self.mainScrollView.frame.size.width && _curPage==_totalNumber-1){
        [ScrollView setBounces:NO];
        [ScrollView setContentOffset:CGPointMake(self.mainScrollView.contentSize.width-self.mainScrollView.frame.size.width, 0) animated:NO];
        [self TheLastOnePage];
    }else{
        
        CGFloat width = self.frame.size.width;
        
        if (_curPage == 0) {
            //第一页往后翻页
            if (x>=width) {
                self.curPage = [self validPageValue:_curPage+1];
            }
        }else if (_curPage == _totalNumber-1){
            //最后一页往前翻页
            if(x <= (self.mainScrollView.contentSize.width-2*width)) {
                self.curPage = [self validPageValue:_curPage-1];
            }
        }else{
            //
            if(x >= (2*width)) {
                //往下翻
                self.curPage = [self validPageValue:_curPage+1];
            }else if (x <= 0) {
                //往上翻
                self.curPage = [self validPageValue:_curPage-1];
            }
        }
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    //mainScrollView显示位置
    if (_curPage==0) {
        [self.mainScrollView setContentOffset:CGPointMake(0, 0)];
    }else if (_curPage==_totalNumber-1){
        [self.mainScrollView setContentOffset:CGPointMake(self.mainScrollView.contentSize.width-self.mainScrollView.bounds.size.width, 0)];
    }else{
        [self.mainScrollView setContentOffset:CGPointMake(self.mainScrollView.frame.size.width, 0)];
    }
}

#pragma mark - 使用手势滑动
- (void)setGestureEnabled:(BOOL)Enabled{
    if (Enabled) {
        [self.mainScrollView setScrollEnabled:NO];
        
        UISwipeGestureRecognizer *swipGestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(next)];
        swipGestureLeft.direction = UISwipeGestureRecognizerDirectionLeft;
        [self.mainScrollView addGestureRecognizer:swipGestureLeft];
        
        UISwipeGestureRecognizer *swipGestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(pre)];
        swipGestureRight.direction = UISwipeGestureRecognizerDirectionRight;
        [self.mainScrollView addGestureRecognizer:swipGestureRight];
        
    }else{
        [self.mainScrollView setScrollEnabled:YES];
    }
}

- (void)next{
    if (_curPage < _totalNumber-1) {
        [self.mainScrollView setUserInteractionEnabled:NO];
        
        CGFloat x = 0;
        if (_curPage == 0) {
            x = self.mainScrollView.frame.size.width;
        }else{
            x = self.mainScrollView.frame.size.width*(MIN(3,_totalNumber)-1);
        }
        
        [self.mainScrollView setContentOffset:CGPointMake(x, 0) animated:YES];
        [self.mainScrollView performSelector:@selector(setUserInteractionEnabled:)
                                  withObject:[NSNumber numberWithBool:YES]
                                  afterDelay:.5];
    }else{
        [self TheLastOnePage];
    }
}

- (void)pre{
    if (_curPage > 0) {
        [self.mainScrollView setUserInteractionEnabled:NO];
        
        CGFloat x = 0;
        if (_curPage == _totalNumber-1 && _totalNumber>=3) {
            x = self.mainScrollView.frame.size.width;
        }
        
        [self.mainScrollView setContentOffset:CGPointMake(x, 0) animated:YES];
        [self.mainScrollView performSelector:@selector(setUserInteractionEnabled:)
                                  withObject:[NSNumber numberWithBool:YES]
                                  afterDelay:.5];
    }else{
        [self TheFirstOnePage];
    }
}

#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
//    CLog(@"%@===",[touch.view class]);
    return YES;
}

/**
 *  第一个View
 */
- (void)TheFirstOnePage{
    if (self.moveExtremum) {
        self.moveExtremum(ScrollViewFirstPage);
    }
}

/**
 *  最后一个View
 */
- (void)TheLastOnePage{
    if (self.moveExtremum) {
        self.moveExtremum(ScrollViewLastPage);
    }
}

@end
